package com.giscloud.amp.service.auth.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.giscloud.amp.core.ServiceConstConfig;
import com.giscloud.amp.dao.AmpStaffAuthMapper;
import com.giscloud.amp.dao.AmpStaffRoleMapper;
import com.giscloud.amp.entity.AmpStaffAuth;
import com.giscloud.amp.entity.AmpStaffAuthExample;
import com.giscloud.amp.entity.dto.AmpStaffAuthDTO;
import com.giscloud.amp.entity.vo.AmpStaffAuthVO;
import com.giscloud.amp.entity.vo.AmpStaffRoleVO;
import com.giscloud.amp.service.auth.AmpStaffAuthService;
import com.giscloud.datasource.page.PageInfo;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author:gxd
 * @Description:
 * @Date: 11:04 2018/2/24
 * @Modified By:
 */
@Service("ampStaffAuthService")
@Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
public class AmpStaffAuthServiceImpl implements AmpStaffAuthService {
    private final static Logger log = LoggerFactory.getLogger(AmpStaffAuthServiceImpl.class);
    @Autowired
    private AmpStaffAuthMapper ampStaffAuthMapper;
    @Autowired
    private AmpStaffRoleMapper ampStaffRoleMapper;
    @Autowired
    private ServiceConstConfig serviceConstConfig;
    @Override
    public List<AmpStaffAuthVO> findRoleByStaff(AmpStaffAuthDTO ampStaffAuthDTO){
    	AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
        criteria.andSystemIdEqualTo(ampStaffAuthDTO.getSystemId());
        criteria.andObjectIdEqualTo(ampStaffAuthDTO.getObjectId());
    	List<AmpStaffAuthVO> ampStaffAuths = ampStaffAuthMapper.selectByExample(ampStaffAuthExample);
    	return ampStaffAuths;
    }

    @Override
    public PageInfo getAmpStaffAuthList(AmpStaffAuthDTO ampStaffAuthDTO) {
        log.debug("#getAmpStaffAuthList parameter ={}", JSON.toJSONString(ampStaffAuthDTO));
        PageHelper.startPage(ampStaffAuthDTO.getPage(), ampStaffAuthDTO.getRows());
        AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
        List<AmpStaffAuthVO> ampStaffAuths = ampStaffAuthMapper.selectByExample(ampStaffAuthExample);
        return PageInfo.of(ampStaffAuths);
    }
    @Override
    public PageInfo getAmpStaffAuthListByDTO(AmpStaffAuthDTO ampStaffAuthDTO) {
        log.debug("#getAmpStaffAuthList parameter ={}", JSON.toJSONString(ampStaffAuthDTO));
        PageHelper.startPage(ampStaffAuthDTO.getPage(), ampStaffAuthDTO.getRows());
        List<AmpStaffAuthVO> ampStaffAuths = ampStaffAuthMapper.selectStaffAuthByDTO(ampStaffAuthDTO);
        return PageInfo.of(ampStaffAuths);
    }
    @Override
    public List<AmpStaffAuthVO> findAmpStaffAuthList(AmpStaffAuthDTO ampStaffAuthDTO) {

        Long userId = 0L;
        if(ampStaffAuthDTO.getStaffId().longValue() == ampStaffAuthDTO.getObjectId().longValue()) {
            userId =ampStaffAuthDTO.getStaffId();
        }else{
            userId =ampStaffAuthDTO.getObjectId();
        }


        AmpStaffAuthExample staffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = staffAuthExample.createCriteria();
        criteria.andSystemIdEqualTo(ampStaffAuthDTO.getSystemId());
        criteria.andStatusCdEqualTo((short)1);
        staffAuthExample.setDistinct(true);
        AmpStaffAuth ampStaffAuth = new AmpStaffAuth();
        BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
        //系统超级管理员拥有全部的权限
        if(ampStaffAuthDTO.getStaffId().toString().equals(serviceConstConfig.getAdminId())){
            return ampStaffAuthMapper.findStaffAuthByExample4Admin(ampStaffAuth,staffAuthExample);
        }
        ampStaffAuth.setObjectId(ampStaffAuthDTO.getStaffId());//先查询登录者拥有的权限
        List<AmpStaffAuthVO> result = ampStaffAuthMapper.findStaffAuthByExample(ampStaffAuth, staffAuthExample);

        //还需要查看用户拥有的角色
        List<AmpStaffRoleVO> roleVOS = ampStaffRoleMapper.findRoleByStaff(userId);
        List<Long> roldeIds = new ArrayList<>();
        for(int k = 0;k<roleVOS.size();k++){
            roldeIds.add(roleVOS.get(k).getRoleId());
        }
        //查看角色所对应的权限，再和用户所拥有的权限求和
        List<AmpStaffAuthVO> tempList = ampStaffAuthMapper.findAuthByStaffAndRole(userId,roldeIds);
        //查询自己所拥有的权限，就直接查
        if(ampStaffAuthDTO.getStaffId().equals(ampStaffAuthDTO.getObjectId())) {
            //result和tempList求并级
            for(int m= 0 ;m<tempList.size();m++){
                AmpStaffAuthVO ampStaffAuthVO = tempList.get(m);
                int k =0;
                for(int n=0 ;n<result.size();n++){
                    if(ampStaffAuthVO.getAuthId().longValue() == result.get(n).getAuthId().longValue()){
                        k=1;
                        break;
                    }

                }
                if(k == 0) {
                    ampStaffAuthVO.setObjectType((short)1);
                    ampStaffAuthVO.setStatusCd((short)1);
                    ampStaffAuthVO.setRelId(-1L);
                    ampStaffAuthVO.setObjectId(userId);
                    result.add(ampStaffAuthVO);
                }
            }
            return result;
        }else {

            //查询他人的权限，就先查看自己拥有的权限，再来求交集
            ampStaffAuthDTO.setStaffId(ampStaffAuthDTO.getObjectId());
            BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
            List<AmpStaffAuthVO> others = ampStaffAuthMapper.findStaffAuthByExampleOther(ampStaffAuth, staffAuthExample);

            for(int m= 0 ;m<tempList.size();m++){
                int k = 0;
                AmpStaffAuthVO ampStaffAuthVO = tempList.get(m);
                for(int n=0 ;n<others.size();n++){
                    if(ampStaffAuthVO.getAuthId().longValue() == others.get(n).getAuthId().longValue()){
                        k =1;
                        break;
                    }
                }
                if(k == 0) {
                    ampStaffAuthVO.setObjectType((short)1);
                    ampStaffAuthVO.setStatusCd((short)1);
                    ampStaffAuthVO.setRelId(-1L);
                    ampStaffAuthVO.setObjectId(userId);
                    others.add(ampStaffAuthVO);
                }
            }

            for(int k=0;k<result.size();k++){
                result.get(k).setRelId(-1L);
                result.get(k).setObjectId(ampStaffAuthDTO.getObjectId());
                result.get(k).setCreatedStaffId(ampStaffAuthDTO.getStaffId());

                result.get(k).setStatusCd((short)2);
                AmpStaffAuthVO my = result.get(k);
                for(int i = 0;i<others.size();i++){
                    if(my.getAuthId().longValue() == others.get(i).getAuthId().longValue()){
                        result.get(k).setRelId(others.get(i).getRelId());
                        result.get(k).setStatusCd(others.get(i).getStatusCd());
                    }
                }
            }
            return result;
        }
    }
    @Override
    //@Cacheable(key= "'amp:findAmpRoleAuthList:'+T(com.alibaba.fastjson.JSON).toJSONString(#ampStaffAuthDTO)",unless="#result==null")
    public List<AmpStaffAuthVO> findAmpRoleAuthList(AmpStaffAuthDTO ampStaffAuthDTO) {
        AmpStaffAuthExample staffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = staffAuthExample.createCriteria();
        criteria.andSystemIdEqualTo(ampStaffAuthDTO.getSystemId());
        if(StringUtils.isNotBlank(ampStaffAuthDTO.getAuthName())){
            criteria.andAuthNameLike("%"+ampStaffAuthDTO.getAuthName()+"%");
        }
        criteria.andStatusCdEqualTo((short)1);
        staffAuthExample.setDistinct(true);
        ampStaffAuthDTO.setStatusCd((short)1);
        AmpStaffAuth ampStaffAuth = new AmpStaffAuth();
        BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
        //查找所有的权限
        List<AmpStaffAuthVO> allList =  ampStaffAuthMapper.findRoleAuthByExample(ampStaffAuth,staffAuthExample);

        AmpStaffAuthExample staffAuthExample1 = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria1 = staffAuthExample1.createCriteria();
        criteria1.andSystemIdEqualTo(ampStaffAuthDTO.getSystemId());

        criteria1.andObjectIdEqualTo(ampStaffAuthDTO.getObjectId());
        criteria1.andObjectTypeEqualTo((short)2);//查找角色的权限
        //系统超级管理员显示全部的权限，包括未启用的,非管理员只能看到启用的权限
        /*if(!ampStaffAuthDTO.getStaffId().toString().equals(serviceConstConfig.getAdminId())){
            criteria1.andStatusCdEqualTo((short)1);
        }*/
        List<AmpStaffAuthVO> getList = ampStaffAuthMapper.selectByExample(staffAuthExample1);
        List<AmpStaffAuthVO> data = new ArrayList<>();
        if(ampStaffAuthDTO.getStaffId().toString().equals(serviceConstConfig.getAdminId())) {
            for (int k = 0; k < allList.size(); k++) {
                allList.get(k).setRelId(-1L);
                allList.get(k).setStatusCd((short) 2);
                for (int i = 0; i < getList.size(); i++) {
                    AmpStaffAuthVO temp = getList.get(i);
                    if (allList.get(k).getAuthId().equals(temp.getAuthId())) {
                        allList.get(k).setRelId(getList.get(i).getRelId());
                        allList.get(k).setStatusCd(getList.get(i).getStatusCd());
                        break;
                    }
                }
            }
            return allList;
        }else{
            for (int k = 0; k < getList.size(); k++) {
                Long relId = getList.get(k).getRelId();
                Short status = getList.get(k).getStatusCd();
                Long objectId = getList.get(k).getObjectId();
                Short objectType = getList.get(k).getObjectType();
                Integer order = getList.get(k).getDispOrder();
                getList.get(k).setRelId(-1L);
                getList.get(k).setStatusCd((short) 2);
                for (int i = 0; i < allList.size(); i++) {
                    AmpStaffAuthVO temp = allList.get(i);
                    if (allList.get(i).getAuthId().equals(getList.get(k).getAuthId())) {
                        BeanUtils.copyProperties(allList.get(i), getList.get(k));
                        getList.get(k).setStatusCd(status);
                        getList.get(k).setRelId(relId);
                        getList.get(k).setObjectId(objectId);
                        getList.get(k).setObjectType(objectType);
                        getList.get(k).setDispOrder(order);
                        break;
                    }
                }
                if(getList.get(k).getAuthName() != null){
                    data.add(getList.get(k));
                }
            }
            return data;
        }
    }

    @Override
    public AmpStaffAuthVO getAmpStaffAuthByCondition(AmpStaffAuthDTO ampStaffAuthDTO) {
        log.debug("#getAmpStaffAuthByCondition parameter ={}", JSON.toJSONString(ampStaffAuthDTO));
        AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
        if(ampStaffAuthDTO.getObjectId()!=null){
            criteria.andObjectIdEqualTo(ampStaffAuthDTO.getObjectId());
        }
        if(ampStaffAuthDTO.getSystemId()!=null){
            criteria.andSystemIdEqualTo(ampStaffAuthDTO.getSystemId());
        }
        if(ampStaffAuthDTO.getAuthId()!=null){
            criteria.andAuthIdEqualTo(ampStaffAuthDTO.getAuthId());
        }
        if(ampStaffAuthDTO.getObjectType()!=null){
            criteria.andObjectTypeEqualTo(ampStaffAuthDTO.getObjectType());
        }
        List<AmpStaffAuthVO> ampStaffAuths = ampStaffAuthMapper.selectByExample(ampStaffAuthExample);
        if(!CollectionUtil.isEmpty(ampStaffAuths) && ampStaffAuths.size() == 1){
            return ampStaffAuths.get(0);
        }else{
            return  null;
        }
    }

    /**
     * 插入时清空缓存
     * @param ampStaffAuthDTO
     * @return
     */
    @Override
    public int insert(AmpStaffAuthDTO ampStaffAuthDTO) {
        AmpStaffAuth ampStaffAuth = new AmpStaffAuth();
        BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
        ampStaffAuth.setCreatedDt(new Date());
        ampStaffAuth.setVersion(new Date());
        return ampStaffAuthMapper.insert(ampStaffAuth);
    }

    /**
     * 更新时清空缓存
     * @param ampStaffAuthDTO
     * @return
     */
    @Override
    public int update(AmpStaffAuthDTO ampStaffAuthDTO) {
        AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
        if(ampStaffAuthDTO.getRelId() != null){
            criteria.andRelIdEqualTo(ampStaffAuthDTO.getRelId());
        }
        AmpStaffAuth ampStaffAuth = new AmpStaffAuth();
        BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
        ampStaffAuth.setCreatedDt(new Date());
        ampStaffAuth.setVersion(new Date());
        return ampStaffAuthMapper.updateByExample(ampStaffAuth,ampStaffAuthExample);
    }

    /**
     * 删除时清空缓存
     * @param relId
     * @return
     */
    @Override
    public int delete(Long relId) {
        AmpStaffAuthExample ampStaffAuthExample = new AmpStaffAuthExample();
        AmpStaffAuthExample.Criteria criteria = ampStaffAuthExample.createCriteria();
        if(relId != null){
            criteria.andRelIdEqualTo(relId);
        }
        return ampStaffAuthMapper.deleteByExample(ampStaffAuthExample);
    }

    @Override
    public List<AmpStaffAuthVO> findAuthByStaffAndRole(AmpStaffAuthDTO ampStaffAuthDTO) {
        List<Long> roles = new ArrayList<>();
        if(ampStaffAuthDTO.getStaffId()!=null){
            List<AmpStaffRoleVO> ampStaffRoleVOS = ampStaffRoleMapper.findRoleByStaff(ampStaffAuthDTO.getStaffId());
            for (int i = 0; i < ampStaffRoleVOS.size(); i++) {
                roles.add(ampStaffRoleVOS.get(i).getRoleId());
            }
        }else{
            roles.add(ampStaffAuthDTO.getRoleId());
        }
        AmpStaffAuth ampStaffAuth = new AmpStaffAuth();
        BeanUtils.copyProperties(ampStaffAuthDTO,ampStaffAuth);
        List<AmpStaffAuthVO> authList = ampStaffAuthMapper.findAuthByStaffAndRole(ampStaffAuthDTO.getStaffId(),roles);
        return ampStaffAuthMapper.findAuthByAuthId(ampStaffAuthDTO.getAuthType(),authList,ampStaffAuthDTO.getSystemId());
    }


    @Override
    public int batchInsert(List<AmpStaffAuthDTO> list) {
        return ampStaffAuthMapper.batchInsert(list);
    }

    @Override
    public int batchUpdate(List<AmpStaffAuthDTO> list) {
        return ampStaffAuthMapper.batchUpdate(list);
    }

}
